#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;

const int NUM = 10;
const int SIZE = 64;

// 包装一个类，类中成员包含要让线程执行工作的变量和执行结果，输入输出

class threadData
{
public:
    threadData(int id, const string &name)
        : _id(id), _name(name), _create_time(time(nullptr))
    {
    }

public:
    int _id;
    string _name;
    time_t _create_time;
};

class cal_threadData : public threadData
{
public:
    cal_threadData(int id, const string &name, int begin, int end)
        : threadData(id, name), _begin(begin), _end(end)
    {
    }

public:
    int _begin;
    int _end;
    int _ret = 0;
};

void *thread_run(void *args)
{
    char *tName = static_cast<char *>(args);

    // threadData *td = static_cast<threadData *>(args);

    cout << "new thread is running..., name: " << tName << endl;

    // // printf("id: %d, name: %s, time: %ld\n", td->_id, td->_name.c_str(), td->_create_time);
    // // sleep(1);

    // 3.线程退出
    // pthread_exit((void *)99);
    return nullptr;
}


void *cal_thread_run(void *args)
{
    cal_threadData *ctd = static_cast<cal_threadData *>(args);

    for (int i = ctd->_begin; i <= ctd->_end; i++)
    {
        ctd->_ret += i;
    }

    delete ctd;

    sleep(3);

    pthread_exit(ctd);
}

int main()
{
    // pthread_t t;
    // pthread_create(&t,nullptr,thread_run,nullptr);

    // 1.创建多个线程
    // pthread_t tids[NUM];
    // for (int i = 0; i < NUM; i++)
    // {
    //     char tName[SIZE] = {0};
    //     snprintf(tName, SIZE, "thread-%d", i + 1);
    //     pthread_create(tids + i, nullptr, thread_run, tName);
    //     sleep(1);
    // }

    // 让多个线程分别执行计算任务（累加begin->end），返回计算结果
    pthread_t tids[NUM];
    for (int i = 0; i < NUM; i++)
    {
        // 2.为每个线程发送特定的数据
        char tName[SIZE] = {0};
        snprintf(tName, SIZE, "thread-%d", i + 1);

        // threadData *td = new threadData(i + 1, tName);

        int begin = rand() % 10 + 1; // [1,10] + [10,100]
        threadData *ctd = new cal_threadData(i + 1, tName, begin, begin * 10);
        pthread_create(tids + i, nullptr, cal_thread_run, ctd);

        if (i + 1 == 5)
        {
            pthread_cancel(tids[i]);
        }
    }

    // int cnt = 5;
    // while (cnt--)
    // {
    //     cout << "main thread is running..." << endl;
    //     sleep(1);
    // }

    for (int i = 0; i < NUM; i++)
    {
        void *ret = nullptr;
        // pthread_join取到pthread_exit输出的指针（填入二级指针ret指向的空间）

        int n = pthread_join(tids[i], &ret);
        if (n == 0)
        {
            if (ret == PTHREAD_CANCELED)
            {
                cout << "线程被取消了" << endl;
            }
            else
            {
                cal_threadData *ctd = static_cast<cal_threadData *>(ret);

                printf("thread complete cal, name: %s  ret: %d  task: [%d,%d]\n",
                       ctd->_name.c_str(), ctd->_ret, ctd->_begin, ctd->_end);
            }
        }

        // cout << tids[i] << ", ret: " << (int64_t)ret << endl;
    }

    return 0;
}
